import 'dart:async';
import 'dart:isolate';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:window_manager/window_manager.dart';
import 'package:xsdk_flutter/xsdk/framework/support/xsdk_navigator_observers.dart';
import 'package:provider/provider.dart';
import 'package:xsdk_flutter/xsdk/xsdk_flutter_package.dart';
/*
App的Base父类

#崩溃日志上传bugly平台  https://bugly.qq.com/v2/crash-reporting/dashboard/00e2d9c059?pid=1

https://pub.dev/packages/tencent_bugly_plugin
dependencies:
  tencent_bugly_plugin: ^0.0.4

import 'package:tencent_bugly_plugin/bugly_config.dart';
import 'package:tencent_bugly_plugin/bugly_plugin.dart';
import 'package:tencent_bugly_plugin/bugly_plugin_method_channel.dart';
import 'package:tencent_bugly_plugin/bugly_plugin_platform_interface.dart';

 */

abstract class XSDKApp extends StatelessWidget with WidgetsBindingObserver {

  /*
  在main.dart中运行app,使用runZonedGuarded包裹运行runApp(MyApp());捕获异常处理
   */
  static void runXSDKApp(
      XSDKApp app,
  {
    Function? initFunction,//执行初始化方法:如bugly
  }
      ){

    /*
    runZonedGuarded处理:异步异常,未预料的未捕获异常
    注意:
    1.Flutter Engine和Native异常，isolate异常 不是runZonedGuarded和FlutterError.onError 能处理范围。
    2.try...catch捕获同步异常
     */
    runZonedGuarded<Future<void>>(() async{
      //初始化
      WidgetsFlutterBinding.ensureInitialized();
      if(XFlutterUtils.isWindows()){
        //
        await windowManager.ensureInitialized();
      }


      if(initFunction!=null){
        /*
      //崩溃日志上传bugly平台 https://pub.dev/packages/tencent_bugly_plugin
      if(XFlutterUtils.isAndroidOriOSSystem()){
        BuglyPlugin.initBugly(
            BuglyConfig(
                androidAppId: "00e2d9c059",
                iosAppId: "ba0b0c6400",
                channel: "xsdk",
                debugMode: false),
            flutterError: (FlutterErrorDetails flutterError) {

              XLogUtils.printLog('BuglyPlugin flutterError捕获异常: ${flutterError.exception}');
              XLogUtils.printLog('BuglyPlugin flutterError捕获异常: ${flutterError.stack}');

              BuglyPlugin.reportException('BuglyPlugin flutterError', flutterError.exception.toString());
            }
        );
      }
       */
        initFunction();
      }


      //Flutter框架Framework(Dart,Flutter)异常捕获
      FlutterError.onError = (FlutterErrorDetails details) async {
        // 开发期间 print
        //FlutterError.dumpErrorToConsole(details);
        //
        //Zone.current.handleUncaughtError(details.exception, details.stack!);

        XLogUtils.printLog('---FlutterError.onError捕获异常: ${details.exception}');
        XLogUtils.printLog('---FlutterError.onError捕获异常: ${details.stack}');

      };

      PlatformDispatcher.instance.onError = (error, stack) {
        XLogUtils.printLog('---PlatformDispatcher捕获异常: $error');
        XLogUtils.printLog('---PlatformDispatcher捕获异常: $stack');
        return true;
      };

      //捕获isolate异常处理
      Isolate.current.addErrorListener(
        RawReceivePort((dynamic pair) async {
          //final isolateError = pair as List<dynamic>;
          XLogUtils.printLog('---Isolate捕获异常: ${XJsonUtils.obj2Json(pair)}');
        }).sendPort,
      );

      //
      runApp(app);

    },(Object error, StackTrace stackTrace){
      // Whenever an error occurs, call the `_reportError` function. This sends
      // Dart errors to the dev console or Sentry depending on the environment.
      XLogUtils.printLog('---runZonedGuarded捕获异常: $error');
      XLogUtils.printLog('---runZonedGuarded捕获异常: $stackTrace');

      // if(XFlutterUtils.isAndroidOriOSSystem()){
      //   //上报日志到Bugly
      //   BuglyPlugin.reportException('runZonedGuarded捕获异常', error.toString());
      // }

    },
    );

  }



  String? titleName;
  int? appRunInBackgroundAutoRestartHours;

  XSDKApp({
    required this.titleName,
    this.appRunInBackgroundAutoRestartHours, //进入后台或息屏时间超过n小时,自动重启app,仅使用android
    super.key,
  });


  @override
  Widget build(BuildContext context){
    //用于XFlutterUtils隐藏键盘api: hideKeyboard
    XFlutterUtils.applicationContext=context;

    //
    _initSystem();

    /*
    监听 App 生命周期,需重写didChangeAppLifecycleState方法
    注意：这里app的生命周期并不是像 Android 那样页面切换的生命周期，而是监听点击 home、物理返回键、屏幕锁定和解锁;
    实测web端不适用?

    取消监听App 生命周期: WidgetsBinding.instance.removeObserver(this);
   */
    WidgetsBinding.instance.addObserver(this);

    //适配iOS点击空白处隐藏键盘
    return MultiProvider(
        providers: [
          ChangeNotifierProvider(create: (_) => XChangeNotifier()),
        ],
        child: XWidgetUtils.getWidgetGestureDetector(
            child: _getMaterialAppWidget(),
            onTap: (){
              //全局点击空白处关闭键盘 注意: 隐藏键盘不要放在XPageStata中实现,否则点击第2次无法关闭输入框,存在bug
              FocusScopeNode currentFocus = FocusScope.of(context);
              if (!currentFocus.hasPrimaryFocus && currentFocus.focusedChild!=null) {
                XLogUtils.printLog('---点击空白处去除当前输入法焦点,隐藏键盘输入法');
                FocusManager.instance.primaryFocus?.unfocus();
              }

            }
        )
    );

  }


  //加载第1页(通常是欢迎页) XPage(()=>XXStatePage())
  @required
  Widget initFirstPage();

  @required
  void initData();

  /////////////////////////////////////
  /*
  指定使用字体:
  1.下载字体;
  2.把字体.ttf放入文件夹中:  assets/fonts/
  3.修改pybspec.yaml文件,添加:

 flutter:
  assets:
    - assets/images/

  fonts:
    - family: pingfang
      fonts:
        - asset: assets/fonts/pingfang_base.ttf
        - asset: assets/fonts/pingfang_mid_black.ttf
        - asset: assets/fonts/pingfang_mid_bold.ttf
   */
  String? getFontFamily(){
    return null;
  }


  //实现多语言////////////////////////////////////////////////////////
  /*
  实现多语言:
1.依赖库:
dependencies:
  intl: any

2.在项目根目录添加:l10n.yaml文件,内容:
arb-dir: lib/src/localization
template-arb-file: app_zh.arb
output-localization-file: app_localizations.dart

3.
在lib/src/localization中,添加app_zh.arb文件,内容:
{
  "testHello":"你好!"
}
在lib/src/localization中,添加app_en.arb文件,内容:
{
  "testHello":"hello world"
}
注意: 在l10n.yaml中设置以app_zh.arb为主,则其他语言的.arb不存在key,则以app_zh.arb为准替代

4.运行命令: flutter gen-l10n  生成对应的key
注意:生成对应的文件在.dart_tool/flutter_gen/l10n中,
如果报错,则需要删除国内镜像再运行(如windows)

5.引入:
import 'package:flutter_gen/gen_l10n/app_localizations.dart';

6.重写方法:
@override
List<LocalizationsDelegate>? getLocalizationsDelegates() {
   return AppLocalizations.localizationsDelegates;
}

@override
List<Locale>? getSupportedLocales() {
   return AppLocalizations.supportedLocales;
}


7.在其他页面中使用:(引入: import 'package:flutter_gen/gen_l10n/app_localizations.dart';)
String txt= AppLocalizations.of(context)!.testHello
注意: 不能在initState()或onCreate()中使用, 因此用到context,则需要在创建后的其他生命周期方法中调用
   */
  List<Locale>? getSupportedLocales(){
    return const <Locale>[Locale('en', 'US')];
  }


  List<LocalizationsDelegate<dynamic>>? getLocalizationsDelegates(){
    //return AppLocalizations.localizationsDelegates;
    return const [
      GlobalMaterialLocalizations.delegate,
      GlobalWidgetsLocalizations.delegate,
      _ChineseCupertinoLocalizationsDelegate(),
    ];
  }


  //私有/////////////////////////////////////////////

  Widget _getMaterialAppWidget(){


    List<Locale>? supportedLocales=getSupportedLocales();
    supportedLocales ??= const <Locale>[Locale('en', 'US')];

    /*
    theme: ThemeData(
        textButtonTheme: TextButtonThemeData(
            style: ButtonStyle()
        ),
        elevatedButtonTheme: ElevatedButtonThemeData(
            style: ButtonStyle()
        ),
        outlinedButtonTheme: OutlinedButtonThemeData(
            style: ButtonStyle()
        )
    ),
       */
    ThemeData xTheme=ThemeData(
      brightness: Brightness.light,
      appBarTheme:  AppBarTheme(
          systemOverlayStyle: SystemUiOverlayStyle(
            statusBarColor: Colors.transparent,
            //实测android和iOS设置相反,默认黑色字体
            statusBarBrightness: XFlutterUtils.isiOS()?Brightness.light:Brightness.dark,
            statusBarIconBrightness: XFlutterUtils.isiOS()?Brightness.light:Brightness.dark,
          )
      ),
      //useMaterial3:true, //默认true
      fontFamily: getFontFamily(),
      //fontFamily: '宋体',
      //checkbox等unselect颜色
      //unselectedWidgetColor:XColorUtils.color999999,
      dividerColor: XColorUtils.dividerColor,
      //visualDensity: VisualDensity.adaptivePlatformDensity,
      cardColor: Colors.white,
      // splashColor: Colors.white,
      indicatorColor: Colors.white,
      hintColor: const Color(0xFF999999),
      //scaffoldBackgroundColor: XColorUtils.pageBackgroundColor,
      // secondaryHeaderColor: Colors.white,
      primaryColor: Colors.white,
      radioTheme: RadioThemeData(
          fillColor:WidgetStateProperty.resolveWith(
                  (Set<WidgetState> states){
                if(states.contains(WidgetState.selected)){
                  //选中状态
                  return XColorUtils.appMainColor;
                }
                return XColorUtils.colorCCCCCC;
              }
          )
      ),
      colorScheme: const ColorScheme.light(
        secondary: Colors.white,
      ),
      progressIndicatorTheme: ProgressIndicatorThemeData(
        color: XColorUtils.appMainColor,
      ),
      popupMenuTheme: const PopupMenuThemeData(
        color: Colors.white,
        surfaceTintColor: Colors.white,
      ),
      cardTheme: const CardTheme(
        surfaceTintColor: Colors.white,
      ),
      iconButtonTheme: IconButtonThemeData(
          style: XStyleUtils.getButtonStyle()
      ),
      dialogTheme:  DialogTheme(
        backgroundColor:Colors.white,
        surfaceTintColor: Colors.white,
        titleTextStyle: XStyleUtils.textStyle_000_16(),
        contentTextStyle: XStyleUtils.textStyle_333_14(),
        actionsPadding: XWidgetUtils.getEdgeInsets(10, 0, 10,5),
        shape: const RoundedRectangleBorder(
          borderRadius:  BorderRadius.all(Radius.circular(10)),
          side: BorderSide.none,
        ),
      ),
      datePickerTheme: const DatePickerThemeData(
        backgroundColor:Colors.white,
        surfaceTintColor:Colors.white,
        shape: RoundedRectangleBorder(
          borderRadius:  BorderRadius.all(Radius.circular(10)),
          side: BorderSide.none,
        ),
      ),
      // cupertinoOverrideTheme: CupertinoThemeData(
      //   textTheme: CupertinoTextThemeData(
      //     textStyle: TextStyle(
      //         color: Colors.black,fontSize: 14,fontWeight: FontWeight.normal),
      //     dateTimePickerTextStyle: TextStyle(
      //         color: Colors.black,fontSize: 14,fontWeight: FontWeight.normal),
      //     pickerTextStyle: TextStyle(
      //         color: Colors.black,fontSize: 14,fontWeight: FontWeight.normal),
      //   ),
      // ),
      switchTheme:SwitchThemeData(
        //滑块颜色
        thumbColor:WidgetStateProperty.resolveWith(
                (Set<WidgetState> states){
              if(states.contains(WidgetState.selected)){
                //选中状态
                return Colors.white;
              }
              return XColorUtils.colorCCCCCC;
            }
        ),
        //轨道背景颜色
        trackColor:WidgetStateProperty.resolveWith(
                (Set<WidgetState> states){
              if(states.contains(WidgetState.selected)){
                //选中状态
                //return const Color(0xFF0068F3);
                return XColorUtils.appMainColor;
              }
              return Colors.white;
            }
        ),
        //轨道边线颜色
        trackOutlineColor:WidgetStateProperty.resolveWith(
                (Set<WidgetState> states){
              if(states.contains(WidgetState.selected)){
                //选中状态
                return null;
              }
              return XColorUtils.colorCCCCCC;
            }
        ),
        //overlayColor: //按压时覆盖的颜色

      ),
      dataTableTheme: const DataTableThemeData(
          dividerThickness:0,
      ),
      checkboxTheme: CheckboxThemeData(
        materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
        visualDensity: VisualDensity.compact,
        shape: RoundedRectangleBorder(
          side: const BorderSide(color: XColorUtils.colorCCCCCC, width: 1.0), // 设置边框颜色和宽度
          borderRadius: BorderRadius.circular(2.0), // 设置边框圆角
        ),
        side: const BorderSide(
            color:XColorUtils.colorCCCCCC,
        ),
      ),
      //选择文本的颜色
      textSelectionTheme: TextSelectionThemeData(
          //selectionColor: Colors.red,
          //selectionHandleColor: Colors.blue
        cursorColor: XColorUtils.appMainColor //光标颜色
      ),
    );


    //使用MaterialApp,Material是一种标准的移动端和web端的视觉设计语言。 Flutter提供了一套丰富的Material widgets。
    return MaterialApp(
      restorationScopeId: 'xsdk_app',
      //locale: const Locale('zh'),
      //showPerformanceOverlay: true,//实测:web端报错
      onGenerateTitle: (BuildContext context) => titleName??'XSDK_Flutter',
      title: titleName??'XSDK_Flutter',
      theme: xTheme,
      darkTheme: xTheme,
      themeMode: ThemeMode.light,
      debugShowCheckedModeBanner: false, //在测试模式中,不在右上角显示debug标签
      //静态路由(界面跳转: Navigator.restorablePushNamed(context, SettingsView.routeName);)
      // onGenerateRoute: (RouteSettings routeSettings) {
      //   return MaterialPageRoute<void>(
      //     settings: routeSettings,
      //     builder: (BuildContext context) {
      //       switch (routeSettings.name) {
      //         case SettingsView.routeName:
      //           return SettingsView(controller: settingsController);
      //         case SampleItemDetailsView.routeName:
      //           return const SampleItemDetailsView();
      //         case SampleItemListView.routeName:
      //         default:
      //           return const SampleItemListView();
      //       }
      //     },
      //   );
      // },
      //全局路由监听
      navigatorObservers: [XSDKNavigatorObserver()],
      //多语言实现
      localizationsDelegates:getLocalizationsDelegates(),
      supportedLocales: supportedLocales,
      home: initFirstPage(),

    );
  }


  Future<void> _initSystem() async {


    //init
    XSharePreferencesUtils.init().then((value){
      XLogUtils.printLog('---XSharePreferencesUtils init success ok: $value');

      XHttpUtils.init();
      XFileUtils.init();

      XFlutterUtils.getDeviceInfo().then((res){
        XTempData.deviceInfo=res;
      });

      XWifiUtils.getWifiIP().then((res){
        XTempData.localWifiIP=res;
      });

      //
      initData();
    });

  }


  ////////////

  int startPausedTime=0;

/*
  监听 App 生命周期(非web),重写方法实现  WidgetsBinding.instance.addObserver(this);
  注意：didChangeAppLifecycleState 管理的生命周期并不是像 Android 那样页面切换的生命周期，而是监听点击 home、物理返回键、屏幕锁定和解锁
   */
  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    if (state == AppLifecycleState.paused) {
      // The application is not currently visible to the user, not responding to
      // user input, and running in the background.
      // 进入后台, 不可见，不可操作
      //实测:app滑动到后台要停留1秒,才执行,如果直接切换其他app进入后台则不会执行,等下次恢复前台才补执行


    }else if (state == AppLifecycleState.resumed) {
      // The application is visible and responding to user input.
      // 进入前台, 可见，可操作
      XLogUtils.printLog('---监听App生命周期,resumed,可见,重新激活屏幕');
      if(startPausedTime!=0
          && appRunInBackgroundAutoRestartHours!=null
          && appRunInBackgroundAutoRestartHours! > 0
          && XFlutterUtils.isAndroid()
      ){
        int nowT=XDateUtils.getCurrentTime_ms();
        if((nowT-startPausedTime)>appRunInBackgroundAutoRestartHours!*60*60*1000){
          XFlutterUtils.restartApp();
        }
      }

      startPausedTime=0;
    }else if (state == AppLifecycleState.inactive) {
      // The application is in an inactive state and is not receiving user input.
      // 过渡时期，不可操作
      XLogUtils.printLog('---监听App生命周期,inactive,可见，不可操作 (过渡时期)');

      XLogUtils.printLog('---监听App生命周期,paused,不可见,进入后台或息屏状态');
      startPausedTime=XDateUtils.getCurrentTime_ms();

    }else if (state == AppLifecycleState.detached) {
      // The application is still hosted on a flutter engine but is detached from any host views.
      // 虽然还在运行，但已经没有任何存在的界面。
      XLogUtils.printLog('---监听App生命周期,detached,虽然还在运行，但已经没有任何存在的界面');
    }

  }


}


class _ChineseCupertinoLocalizations extends DefaultCupertinoLocalizations {
  const _ChineseCupertinoLocalizations();

  @override
  String timerPickerHourLabel(int hour) => '时';

  @override
  List<String> get timerPickerHourLabels => const <String>['时'];

  @override
  String timerPickerMinuteLabel(int minute) => '分';

  @override
  List<String> get timerPickerMinuteLabels => const <String>['分'];

  @override
  String timerPickerSecondLabel(int second) => ' 秒';

  @override
  List<String> get timerPickerSecondLabels => const <String>[' 秒'];

}

class _ChineseCupertinoLocalizationsDelegate
    extends LocalizationsDelegate<CupertinoLocalizations> {
  const _ChineseCupertinoLocalizationsDelegate();

  @override
  bool isSupported(Locale locale) => true;

  @override
  Future<CupertinoLocalizations> load(Locale locale) async {
    return _ChineseCupertinoLocalizations();
  }

  @override
  bool shouldReload(_ChineseCupertinoLocalizationsDelegate old) => false;
}